package com.woniu.order.config;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * 生产者可靠投递配置
 */
@Configuration
@Slf4j
public class CallbackConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @PostConstruct
    public void init(){
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
        rabbitTemplate.setMandatory(true);
    }


    /**
     * 消息发送到交换机确认回调，消息是否成功收到
     * @param correlationData correlation data for the callback.
     * @param ack true for ack, false for nack
     * @param cause An optional cause, for nack, when available, otherwise null.
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) return;//消息成功发送则不处理
        log.error("消息发送失败，correlationData:{},ack:{},cause:{}",correlationData,ack,cause);
        //重新发送消息（上限：5左右，每次重发时间的间隔会不一样）或者保存到数据库（1.人工处理 2.定时任务：定时扫描数据库，把未发送成功的消息进行再次发送）
        //保存到数据库需要字段：消息体，交换机名称，路由键
        byte[] body = correlationData.getReturnedMessage().getBody();
        String receivedExchange = correlationData.getReturnedMessage().getMessageProperties().getReceivedExchange();
        String receivedRoutingKey = correlationData.getReturnedMessage().getMessageProperties().getReceivedRoutingKey();
        log.error("消息发送失败，消息体：{},交换机名称：{},路由键：{}",new String(body),receivedExchange,receivedRoutingKey);

        saveMessage(body, receivedExchange, receivedRoutingKey);
    }



    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        log.error("消息发送失败，message：{},replyCode：{},replyText：{},exchange:{},routingKey:{}",
                message, replyCode, replyText, exchange, routingKey);

        saveMessage(message.getBody(), exchange, routingKey);
    }


    private void saveMessage(byte[] body, String receivedExchange, String receivedRoutingKey) {

    }
}
